<?php
/**
 * <i>@options</i>组件
 * 
 * 可以使用的参数有：
 * - x-options 选项数组
 * - [x-selected-values] array/string 选中的选项
 * - [x-selected-texts]  array/string 选中的文本  
 * - [x-before] string 在已有选项的前面，仅有true可选
 * - [x-after] string 在已有选项的后面，仅有true可选
 * - [x-value-key] 值得键，和x-text-key配合使用
 * - [x-text-key] 文本的键  
 * 
 * 从0.1开始，可以使用{$yield.options}存放处理过程
 * 
 * 示例：<br>
 *  模板：<br>
 * <pre>
 *   <select com="@options" x-options="$students" x-selected-values="$studentsSelected" x-selected-texts="$selectedTexts">
 *	 </select>
 * </pre>
 *  程序：
 * <code>
 *   $dataSet = array();
 *	 $dataSet["students"] = array("a", "b", "c", "d", "e", "f", "f", "g");
 *	 $dataSet["studentsSelected"] = array(2, 3, 5, 6);
 *	 $dataSet["selectedTexts"] = "d";
 *	 return new IModelAndTemplate($dataSet, "test");
 * </code>
 * 
 * x-value-key/x-text-key使用示例：<br/>
 *  模板
 * <pre>
 * <select com="@options" x-options="$users" x-value-key="id" x-text-key="name">
 * </select>
 * </pre>
 *  程序
 * <code>
 * 	public function appIndex() {
 * 		$this->users = array(
 * 			array("id"=>1, "name"=>"iwind"),
 * 			array("id"=>2, "name"=>"peter"),
 * 			array("id"=>3, "name"=>"danny")
 * 		);
 * 	}
 * </code>
 *  结果
 * <pre>
 * <select><option value="1">iwind</option>
 * <option value="2">peter</option>
 * <option value="3">danny</option>
 * </select>
 * </pre>
 * 
 * @version $Id: IMintOptionsComponent.php 312 2008-04-23 16:29:38Z iwind $
 * @package util.mint.component
 */
class IMintOptionsComponent extends IAbstractMintComponent {
	/**
	 * 取得支持的参数列表
	 *
	 * @return array
	 */	
	public function getSupportedParameters() {
		return array("x-options", "x-selected-values", "x-selected-texts", "x-before", "x-after", "x-value-key", "x-text-key");
	}
	
	/**
	 * 取得HTML属性映射
	 *
	 * @return array
	 * @since 0.0.3
	 */		
	public function getHtmlAttrMapping() {
		return array();
	}	
	
	/**
	 * 处理组件
	 *
	 * @return boolean
	 */	
	public function processComponent() {
		$parameters = $this->getParameters();
		if (!isset($parameters["x-options"])) {
			return false;
		}
		
		//value/text keys
		$valueKey = $this->getParameterValue("x-value-key");
		$textKey = $this->getParameterValue("x-text-key");
		
		//x-options
		$xOptionsVar = new IMintVariable($parameters["x-options"]);
		if (!$xOptionsVar->isValid()) {
			$this->throwVariableException("x-options");
		}
		$xOptions = $xOptionsVar->getVarname();
		$text = "<?php \n";
		$text .= $xOptionsVar->getParseProcess();
		$text .= "if(is_array($xOptions)){\n";
		if ($valueKey !== null && $textKey !== null) {
			$valueKey = addslashes($valueKey);
			$textKey = addslashes($textKey);
			$tmpArray = "\$" . $this->getUniqid();
			$tmpValue = "\$" . $this->getUniqid();
			$text .= "{$tmpArray}=array();\n";
			$text .= "foreach({$xOptions} as {$tmpValue}){\n";
			$text .= "if(!is_array({$tmpValue}) && !is_object({$tmpValue})){\ncontinue;}\n";
//			$text .= "if(array_key_exists(\"{$valueKey}\",{$tmpValue})&&array_key_exists(\"{$textKey}\",{$tmpValue})){\n";
			$text .= "{$tmpArray}[IReflection::getProperty({$tmpValue},\"{$valueKey}\")]=IReflection::getProperty({$tmpValue},\"{$textKey}\");\n";
//			$text .= "}\n";
			$text .= "}\n";
			$text .= "{$xOptions}={$tmpArray};\n";
		}
		$text .= " foreach({$xOptions} as \$optionValue=>\$optionText) {\n";
		if (isset($parameters["x-selected-values"])) {
			$selectedValues = $parameters["x-selected-values"];
			$xValues = IMintVariable::getDefinition($selectedValues);
			if ($xValues == null) {
				$this->throwVariableException("x-selected-values");
			}
			$text .= "if (!is_array({$xValues})) {
				{$xValues} = array({$xValues});
			 }";
		}
		if (isset($parameters["x-selected-texts"])) {
			$selectTexts = $parameters["x-selected-texts"];
			$xText = IMintVariable::getDefinition($selectTexts);
			$text .= "if (!is_array({$xText})) {
				{$xText} = array({$xText});
			 }";
		}
		if (isset($xValues)) {
			if (isset($xText)) {
				 $text .= "if (in_array(\$optionValue, $xValues) || in_array(\$optionText, $xText)) {echo \"<option value=\\\"\" . htmlspecialchars(\$optionValue) . \"\\\" selected>\" . \$optionText . \"</option>\n\";}
				 else {
					echo \"<option value=\\\"\" . htmlspecialchars(\$optionValue) . \"\\\">\" . \$optionText . \"</option>\n\";
				 }\n";
			}
			else {
				 $text .= "if (in_array(\$optionValue, $xValues)) {echo \"<option value=\\\"\" . htmlspecialchars(\$optionValue) . \"\\\" selected>\" . \$optionText . \"</option>\n\";}
				 else {
					echo \"<option value=\\\"\" . htmlspecialchars(\$optionValue) . \"\\\">\" . \$optionText . \"</option>\n\";
				 }\n";
			}
		}
		else {
			if (isset($xText)) {
				 $text .= "if (in_array(\$optionText, $xText)) {echo \"<option value=\\\"\" . htmlspecialchars(\$optionValue) . \"\\\" selected>\" . \$optionText . \"</option>\n\";}
				 else {
					echo \"<option value=\\\"\" . htmlspecialchars(\$optionValue) . \"\\\">\" . \$optionText . \"</option>\n\";
				 }\n";	
			}
			else {
				$text .= "echo \"<option value=\\\"\" . htmlspecialchars(\$optionValue) . \"\\\">\" . \$optionText . \"</option>\n\";";
			}
		}
		$text .= "}";
		$text .= "} \n ?>";

		if (isset($parameters["x-before"]) && trim($parameters["x-before"]) == "true") {
			$this->addFirstChildScript($text);
		}
		else if (isset($parameters["x-after"]) && trim($parameters["x-after"]) == "true") {
			$this->addLastChildScript($text);
		}	
		else if ($this->containsYield("yield.options")) {
			$this->replaceYield("yield.options", $text);
		}
		else {
			$this->addLastChildScript($text);
		}
		return true;
	}
}

?>